package com.elitecrm.chatesop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class apiCallback extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final Log log = LogFactory.getLog(apiCallback.class);

    private static final String classString = "apiCallback";
    private String apiURL;
    private String errorURL;

    public void destroy() {
        super.destroy();
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 调用类型校验,此接口仅支持GET
        String getMethod = request.getMethod();
        log.debug("getMethod:" + getMethod);

        // 获取所有Header
        Map<String, String> mapHeader = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            log.debug("Call Header-" + key + ":" + value);

            mapHeader.put(key, value);
        }

        // 获取所有参数名
        Map<String, String> mapParams = new HashMap<String, String>();
        Enumeration ep = request.getParameterNames();
        while (ep.hasMoreElements()) {
            String key = (String) ep.nextElement();
            String value = request.getParameter(key);
            log.debug("Call Parameter-" + key + ":" + value);
            mapParams.put(key, value);

        }

        log.debug("原始Get请求参数 mapParams:" + mapParams.toString());

        // 获取token
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        CloseableHttpResponse callResp = null;
        log.debug("要转发的地址：" + apiURL);
        try {
            // 拼接参数
            String queryStr = getQueryString(mapParams);

            // 调用内部接口
            callResp = httpClient.execute(new HttpGet(apiURL + "?" + queryStr));
            HttpEntity entity = callResp.getEntity();
            int status = callResp.getStatusLine().getStatusCode();
            response.setStatus(status);
            if (status == 200 && entity != null) {

                // 获取响应头
                Header[] headers = callResp.getAllHeaders();

                // 获取接口返回
                String result = EntityUtils.toString(entity, "UTF-8");

                if (isNull(result)) {
                    log.warn("接口返回结果为空：" + result);
                    errorRedirect(response, "地址异常", "接口返回结果为空：" + result);

                } else if (result.startsWith("http")) {
                    log.warn("接口返回重定向地址：" + result);
                    response.sendRedirect(result);

                } else {
                    response.setCharacterEncoding("utf-8");
                    PrintWriter out = response.getWriter();
                    out.print(result);

                }
            } else {
                errorRedirect(response, "登录处理异常", "登录处理异常错误:无重定向URL");
            }
        } catch (Exception e) {
            log.error("处理异常", e);
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (callResp != null) {
                    callResp.close();
                }
            } catch (IOException e) {
                log.error("关闭流异常", e);
            }
        }

    }

    public void init() throws ServletException {
        log.info("接口服务" + classString + " 初始化开始...");
        this.apiURL = getInitParameter("apiURL");
        this.errorURL = getInitParameter("errorURL");
        log.info("接口服务" + classString + " 初始化完成... apiURL:" + apiURL + " errorURL:" + errorURL);
    }

    // 异常&错误重定向
    public void errorRedirect(HttpServletResponse response, String ErrorTitle, String ErrorInfo) throws IOException {
        log.warn("异常&错误[apiDynLogin]重定向 ErrorTitle:" + ErrorTitle + " ErrorInfo:" + ErrorInfo);
        ErrorTitle = isNull(ErrorTitle) ? "页面异常" : ErrorTitle;
        ErrorInfo = isNull(ErrorInfo) ? "请稍后再试或联系管理员." : ErrorInfo;
        response.sendRedirect(this.errorURL + "/404.html?ErrorTitle=" + encode(ErrorTitle) + "&ErrorInfo=" + encode("登录异常&错误:" + ErrorInfo).replaceAll("\\+", "%20"));
    }

    // 工具方法
    public static String getQueryString(Map<String, String> params) {
        String url = "";
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
            builder.append(encode(value));

            i++;
        }

        return builder.toString();
    }

    // 工具方法
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }

    // 解析Mapn值(此方法增加需要解析的key不存在保护)
    public static String GetMapV(Map inMap, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = String.valueOf(inMap.get(getKey));
        } catch (Exception e) {

            Rev_Value = "";
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    // 非空校验isNull
    public static boolean isNull(String value) {

        boolean reFlag = true;
        if (value == null || value.length() <= 0) {
            reFlag = true;
        } else {
            reFlag = false;
        }

        return reFlag;
    }
}